package com.signway.utils;

import android.util.Log;

import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Locale;
import java.util.regex.Pattern;

/**
 * 字符类转换常用工具
 */
public class CharTools {
    private static final String TAG = "CharTools";

    private static final byte ASCII_0 = 0x30;
    private static final byte ASCII_9 = 0x39;
    private static final byte ASCII_A = 0x41;
    private static final byte ASCII_Z = 0x5A;
    private static final byte ASCII_a = 0x61;
    private static final byte ASCII_z = 0x71;

    public static int getRandomInt() {
        return (int) (Math.random() * 100000);
    }

    public static int getRandomDoubleByteInt() {
        return (int) (Math.random() * 50000);
    }

    public static int getRandomPort() {
        return (int) (5000 + Math.random() * 5000);
    }

    public static long getReverseNum(long num) {
        return num ^ 0xFFFFFFFFFFFFFFFFl;
    }

    public static float percent2f(String percent) {
        float ret = 0f;
        if (percent == null || percent.length() < 2) {
            return ret;
        }
        ret = Float.parseFloat(percent.substring(0, percent.length() - 1));
        return (ret / 100);
    }

    public static int getPxSize(String size) {
        int ret = 0;

        if (size == null) {
            return 0;
        }

        if (size.toLowerCase().endsWith("px")) {
            try {
                ret = Integer.parseInt(size.toLowerCase().substring(0, size.toLowerCase().indexOf("px")));
            } catch (Exception e) {
                ret = 0;
            }
        }

        return ret;
    }

    /**
     * 将指定byte数组以16进制的形式打印到控制台
     *
     * @param b
     * @return
     */
    public static String printHexString(byte[] b, int length) {
        if (length > b.length) {
            Log.e(TAG, "printHexString: b.length = " + b.length + " length = " + length);
            return null;
        }
        StringBuilder buf = new StringBuilder();
        buf.append("[" + length + "]");
        for (int i = 0; i < length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            buf.append(hex.toUpperCase());
        }
        return buf.toString();
    }

    /**
     * compare two byte array
     */
    public static boolean compareByte(byte[] b1, int off_b1, byte[] b2, int off_b2, int len) {
        if (b1.length < (off_b1 + len)) {
            return false;
        }

        if (b2.length < (off_b2 + len)) {
            return false;
        }

        if ((off_b1 < 0) || (off_b2 < 0)) {
            return false;
        }

        if (len < 0) {
            return false;
        }

        for (int i = 0; i < len; i++) {
            if (b1[off_b1 + i] != b2[off_b2 + i]) {
                return false;
            }
        }

        return true;
    }

    public static boolean isAllABC123(byte[] src, int length) {
        if (src == null || src.length < length) {
            return false;
        }

        for (int i = 0; i < length; i++) {
            if ((src[i] <= ASCII_9 && src[i] >= ASCII_0)
                    || (src[i] <= ASCII_Z && src[i] >= ASCII_A)
                    || (src[i] <= ASCII_z && src[i] >= ASCII_a)) {
                continue;
            }
            return false;
        }
        return true;
    }

    public static boolean isAll123(byte[] src, int length) {
        if ((src == null) || (length <= 0) || (src.length < length)) {
            return false;
        }
        for (int i = 0; i < length; i++) {
            if ((src[i] <= ASCII_9) && (src[i] >= ASCII_0)) {
                continue;
            }
            return false;
        }
        return true;
    }

    public static float FormetFloat(float text) {
        DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.CHINESE);
        DecimalFormat fmt = new DecimalFormat("0.##", symbols);
        String aa = fmt.format(text);
        return Float.parseFloat(aa);
    }

    /**
     * 判断字符串是否为数字格式
     *
     * @param str
     * @return
     */
    public static boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("^[0-9]+$");
        return pattern.matcher(str).matches();
    }

    /**
     * 判断字符串是否合法
     *
     * @param str
     * @return
     */
    public static boolean isValidString(String str) {
        Pattern pattern = Pattern.compile("^[A-Za-z0-9]+$");
        return pattern.matcher(str).matches();
    }

    public static String getISO8859Str(byte[] data, int offset, int length) {
        try {
            return new String(data, 0, length, "ISO-8859-1");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return null;
    }

    public static byte[] getISO8859ByteArray(String str) {
        try {
            if (str != null)
                return str.getBytes("ISO-8859-1");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return null;
    }

    public static byte[] getBytes(String text) {
        if (text == null) {
            return new byte[8];
        }
        if (text.length() < 2) {
            return new byte[8];
        }
        byte[] oldPwdByte = new byte[text.length() / 2];
        for (int i = 0; i < text.length(); i = i + 2) {
            try {
                oldPwdByte[(i + 1) / 2] = (byte) (Integer.parseInt(text.substring(i, i + 2), 16) & 0xff);
            } catch (Exception e) {
                Log.e(TAG, "getBytes - inputStr invalid: " + e.toString());
            }
        }
        return oldPwdByte;
    }

    public static byte getByte(String s) {
        char ch0 = s.charAt(0);
        char ch1 = s.charAt(1);
        byte result = 0;
        if (ch0 > '9') {
            result = (byte) ((ch0 - 'A' + 10) * 16);
        } else {
            result = (byte) ((ch0 - '0') * 16);
        }

        if (ch1 > '9') {
            result += (ch1 - 'A' + 10);
        } else {
            result += (ch1 - '0');
        }

        result = (byte) (result & 0xff);
        return result;
    }

    /**
     * {0, 0, 0, 0}转为int数组
     *
     * @param value
     * @return
     */
    public static int[] getIntegerCoordinate(String value) {
        if ((value == null) || "".equals(value)) {
            return new int[]{0, 0, 0, 0};
        }

        String[] str = value.split(",");
        if ((str == null) || (str.length != 4)) {
            Log.i(TAG, "params error");
            return new int[]{0, 0, 0, 0};
        }

        int[] coo = new int[4];

        try {
            for (int i = 0; i < 4; i++) {
                coo[i] = Integer.parseInt(str[i]);
            }
        } catch (Exception e) {
            Log.i(TAG, "params data error");
            return new int[]{0, 0, 0, 0};
        }

        int x = coo[0];
        int y = coo[1];
        int w = coo[2] - coo[0];
        int h = coo[3] - coo[1];
        if (w < 0) {
            w = 0;
        }

        if (h < 0) {
            h = 0;
        }

        coo[0] = x;
        coo[1] = y;
        coo[2] = w;
        coo[3] = h;

        return coo;
    }

    static class ListStringCompare implements Comparator {

        @Override
        public int compare(Object lhs, Object rhs) {
            String str1 = (String) lhs;
            String str2 = (String) rhs;

            return str1.compareTo(str2);
        }
    }

    public static void sortStringList(ArrayList<String> list) {
        if (list == null || list.size() <= 0) {
            return;
        }

        Collections.sort(list, new ListStringCompare());
    }

    public static void clearIntArray(int[] arr) {
        if (arr == null) {
            return;
        }

        for (int i = 0; i < arr.length; i++) {
            arr[i] = 0;
        }
    }

    public static void copyIntArray2Array(int[] src, int[] des) {
        if ((src == null) || (des == null)) {
            return;
        }

        clearIntArray(des);

        System.arraycopy(src, 0, des, 0, src.length);
    }

    /**
     * 获取2个值中的最大数
     *
     * @param value
     * @param max
     * @return
     */
    public static int getMaxValue(int value, int max) {
        return (value > max) ? value : max;
    }

    /**
     * 获取2个值中的最小数
     *
     * @param value
     * @param min
     * @return
     */
    public static int getMinValue(int value, int min) {
        return (value > min) ? min : value;
    }

    /**
     * 获取min、max之间的正确区间值
     *
     * @param value
     * @param min
     * @param max
     * @return
     */
    public static int getIntervalValue(int value, int min, int max) {
        return getMinValue(getMaxValue(value, min), max);
    }

    /**
     * 大端模式，低字节在低位   0x12345678  b[0] = 0x12
     *
     * @param n
     * @return
     */
    public static byte[] intToBytesArray(int n) {
        byte[] b = new byte[4];

        for (int i = 0; i < 4; i++) {
            b[3 - i] = (byte) (n >> (24 - i * 8));
        }

        return b;
    }

    /**
     * 大端模式，低字节在低位   0x12345678  b[0] = 0x12
     *
     * @param n
     * @return
     */
    public static byte[] longToBytesArray(long n) {
        byte[] b = new byte[8];

        for (int i = 0; i < 8; i++) {
            b[7 - i] = (byte) (n >> (56 - i * 8));
        }

        return b;
    }

    /**
     * 计算需要转成字符串的数组的长度
     *
     * @param data
     * @return
     */
    public static int arrayStringLength(byte[] data) {
        int i = 0;
        for (i = 0; i < data.length; i++) {
            if (data[i] == 0x00) {
                break;
            }
        }
        return i;
    }

    public static int absByte(byte buf) {
        int abs = 0;

        if (buf < 0) {
            abs = 256 + buf;
        } else {
            abs = buf;
        }

        return abs;
    }

    /**
     * Byte数组转换为16进制字符串
     *
     * @param bs 待转换Byte数组
     * @return转换后的16进制字符串，Byte之间用空格分开，每16个Byte换行
     */
    public static String bytes2HexStr(byte[] bs) {
        String temp = "";
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bs.length; i++) {
            temp = Integer.toHexString(bs[i] & 0xff);
            sb.append((temp.length() == 1) ? "0" + temp : temp);
            if (i != 0 && i % 16 == 0) {
                sb.append("\n");
            }
        }
        return sb.toString().toUpperCase().trim();
    }

    public static byte[] stringToHex(String inputStr) {
        byte[] result = new byte[inputStr.length() / 2];
        for (int i = 0; i < inputStr.length() / 2; ++i) {
            try {
                result[i] = (byte) (Integer.parseInt(inputStr.substring(i * 2, i * 2 + 2), 16) & 0xff);
            } catch (Exception e) {
                Log.e(TAG, "stringToHex - inputStr invalid: " + e.toString());
            }
        }
        return result;
    }

    public static byte hex2str(byte src, int mode) {
        byte temp;
        byte ret = 0;

        temp = (byte) (src >> (mode * 4));
        temp &= 0xf;

        if ((temp >= 0x0a) && (temp <= 0x0f))
            ret = (byte) (temp + 'A' - 0x0a);
        else if ((temp >= 0) && (temp <= 9))
            ret = (byte) (temp + '0');

        return ret;
    }

    public static int Le32_2_Be32(byte[] buf, int start) {
        int be = 0;

        be = (buf[start] & 0xff) << 24;
        be |= (buf[start + 1] & 0xff) << 16;
        be |= (buf[start + 2] & 0xff) << 8;
        be |= (buf[start + 3] & 0xff);

        return be;
    }

    public static int BCDToInt8(int x) {
        int y = 0;
        y = (((x) >> 4) & 0xf) * 10 + ((x) & 0xf);
        return y;
    }

    public static int Int8ToBCD(int x) {
        int y = 0;
        y = (((x) / 10) << 4) | ((x) % 10);
        return y;
    }

    public static void long2Byte(byte[] bb, long x, int offset) {
        bb[offset + 0] = (byte) (x >> 56);
        bb[offset + 1] = (byte) (x >> 48);
        bb[offset + 2] = (byte) (x >> 40);
        bb[offset + 3] = (byte) (x >> 32);
        bb[offset + 4] = (byte) (x >> 24);
        bb[offset + 5] = (byte) (x >> 16);
        bb[offset + 6] = (byte) (x >> 8);
        bb[offset + 7] = (byte) (x >> 0);
    }

    public static long byte2Long(byte[] bb, int offset) {
        return ((((long) bb[offset + 0] & 0xFF) << 56) | (((long) bb[offset + 1] & 0xFF) << 48)
                | (((long) bb[offset + 2] & 0xFF) << 40) | (((long) bb[offset + 3] & 0xFF) << 32)
                | (((long) bb[offset + 4] & 0xFF) << 24) | (((long) bb[offset + 5] & 0xFF) << 16)
                | (((long) bb[offset + 6] & 0xFF) << 8) | (((long) bb[offset + 7] & 0xFF) << 0));
    }
}
